package com.fengxu.netty.simple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

// 服务器管道处理器
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    // 读取通道中的数据
    // ChannelHandlerContext 上下文,含有pipeline管道,channel通道,地址等
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        System.out.println("ctx = "+ ctx);
//        ByteBuf byteBuf = (ByteBuf) msg;
//        System.out.println("客户端发送的消息是:"+byteBuf.toString(CharsetUtil.UTF_8));
//        System.out.println("客户端地址:"+ctx.channel().remoteAddress());
//        // pipeline底层是双向链表
//        System.out.println("管道是:"+ctx.pipeline());
//    }

    // 解决耗时任务
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("客户端发送的消息是:"+byteBuf.toString(CharsetUtil.UTF_8));

        // 方案一: 用户自定义普通任务(该任务会被提交到与该channel关联的NIOEventLoop的taskQueue中去)
        ctx.channel().eventLoop().execute(()->{
            try {
                Thread.sleep(1000*10);
                ctx.writeAndFlush(Unpooled.copiedBuffer("服务器执行完了耗时任务1!",CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("产生异常!");
            }
        });

        // 方案二:用户自定义定时任务(该任务会被提交到与该channel关联的NIOEventLoop的scheduledTaskQueue中去)
        // 该任务会在与该channel关联的NIOEventLoop的taskQueue中的任务全部执行完毕后再去执行
        ctx.channel().eventLoop().schedule(()->{
            try {
                Thread.sleep(1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("服务器执行完了耗时任务2!",CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("产生异常!");
            }
        },5, TimeUnit.SECONDS);
        System.out.println("服务器执行完毕读取事件!");
    }

    // 通道读取完毕事件
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 将数据写入缓冲区并flush
        ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端",CharsetUtil.UTF_8));
    }

    // 异常处理,一般是关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
